#pragma once
#include "pch.h"

using namespace DirectX;
using namespace Microsoft::WRL;

class D3D12DeviceWrapper
{
private:
	HWND m_hwnd;
	int m_width;
	int m_height;
	UINT m_frameCount;
	int m_frameIndex;
	int m_rtvDescriptorSize;

	ComPtr<ID3D12Fence> m_fence;
	UINT64 m_fenceValue;
	HANDLE m_fenceEvent;

	ComPtr<ID3D12CommandQueue> m_commandQueue;
	ComPtr<IDXGISwapChain3> m_swapChain;
	ComPtr<ID3D12Device> m_device;
	ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
	std::vector<ComPtr<ID3D12Resource>> m_renderTargets;
	ComPtr<ID3D12Resource> m_depthStencil;
	ComPtr<ID3D12DescriptorHeap> m_dsvHeap;

	void GetHardwareAdapter(_In_ IDXGIFactory2* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter);

public:
	D3D12DeviceWrapper(HWND hwnd, UINT width, UINT height);
	void Present();
	void CreateDevice();
	void CreateRenderTarget();
	void CreateDepthStencil();
	HRESULT CreateCommandList(ComPtr<ID3D12CommandAllocator>& commandAllocator, ComPtr<ID3D12GraphicsCommandList>& commandList);
	void WaitGpu();
	void PostCommand(ID3D12GraphicsCommandList* commandList);

	ID3D12Device* GetDevice() { return m_device.Get(); }
	ID3D12CommandQueue* GetCommandQueue() { return m_commandQueue.Get(); };
	ID3D12DescriptorHeap* GetDepthStencilHeap() { return m_dsvHeap.Get(); };
	ID3D12Resource* GetRenderTargetResource() { return m_renderTargets[m_frameIndex].Get(); }
	CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetHandle()
	{
		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
		return rtvHandle;
	}

};

